package com.njmaomao.gj.pyot.domain.wechat.wechatapi.orderquery;

import com.njmaomao.gj.pyot.domain.wechat.wechatapi.ApiResp;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import org.apache.commons.lang3.time.DateUtils;

import java.text.ParseException;
import java.util.Date;
import java.util.Optional;

/**
 * 查询订单出参
 * @author hh 2018-5-10
 */
@XStreamAlias("xml")
public class OrderQueryResp implements ApiResp {

    // 返回状态码  必填[是 ] SUCCESS/FAIL 此字段是通信标识，非交易标识，交易是否成功需要查看trade_state来判断
    @XStreamAlias("return_code")
    private String returnCode ;

    // 返回信息  必填[否 ]返回信息，如非空，为错误原因
    @XStreamAlias("return_msg")
    private String  returnMsg ;

    // 公众账号ID  必填[是 ] 微信分配的公众账号ID
    private String  appid ;

    // 商户号  必填[是 ] 微信支付分配的商户号
    @XStreamAlias("mch_id")
    private String  mchId ;

    // 随机字符串  必填[是 ] 随机字符串，不长于32位。推荐随机数生成算法
    @XStreamAlias("nonce_str")
    private String  nonceStr ;

    // 签名  必填[是 ] 签名，详见签名生成算法
    private String  sign ;

    // 业务结果  必填[是 ] SUCCESS/FAIL
    @XStreamAlias("result_code")
    private String  resultCode ;

    // 错误代码  必填[否 ] 错误码
    @XStreamAlias("err_code")
    private String  errCode ;

    // 错误代码描述  必填[否 ] 结果信息描述
    @XStreamAlias("err_code_des")
    private String  errCodeDes ;

    // 设备号  必填[否 ] 微信支付分配的终端设备号，
    @XStreamAlias("device_info")
    private String  deviceInfo ;

    // 用户标识  必填[是 ] 用户在商户appid下的唯一标识
    private String  openid ;

    // 是否关注公众账号  必填[否 ] 用户是否关注公众账号，Y-关注，N-未关注，仅在公众账号类型支付有效
    @XStreamAlias("is_subscribe")
    private String  isSubscribe ;

    // 交易类型  必填[是 ] 调用接口提交的交易类型，取值如下：JSAPI，NATIVE，APP，MICROPAY，详细说明见参数规定
    @XStreamAlias("trade_type")
    private String  tradeType ;

    // 交易状态  必填[是 ] SUCCESS—支付成功 REFUND—转入退款 NOTPAY—未支付 CLOSED—已关闭 REVOKED—已撤销（刷卡支付）USERPAYING--用户支付中 PAYERROR--支付失败(其他原因，如银行返回失败)支付状态机请见下单API页面
    @XStreamAlias("trade_state")
    private String tradeState ;

    // 付款银行  必填[是 ] 银行类型，采用字符串类型的银行标识
    @XStreamAlias("bank_type")
    private String  bankType ;

    // 标价金额 必填[是 ] 订单总金额，单位为分
    @XStreamAlias("total_fee")
    private int  totalFee ;

    // 应结订单金额 必填[否 ] 当订单使用了免充值型优惠券后返回该参数，应结订单金额=订单金额-免充值优惠券金额。
    @XStreamAlias("settlement_total_fee")
    private int  settlementTotalFee ;

    // 标价币种 必填[否 ] 货币类型，符合ISO 4217标准的三位字母代码，默认人民币：CNY，其他值列表详见货币类型
    @XStreamAlias("fee_type")
    private String  feeType ;

    // 现金支付金额  必填[是 ] 现金支付金额订单现金支付金额，详见支付金额
    @XStreamAlias("cash_fee")
    private int  cashFee ;

    // 现金支付币种  必填[否 ] 货币类型，符合ISO 4217标准的三位字母代码，默认人民币：CNY，其他值列表详见货币类型
    @XStreamAlias("cash_fee_type")
    private String  cashFeeType ;

    // 代金券金额  必填[否 ] “代金券”金额<=订单金额，订单金额-“代金券”金额=现金支付金额，详见支付金额
    @XStreamAlias("coupon_fee")
    private int  couponFee ;

    // 代金券使用数量  必填[否 ] 代金券使用数量
    @XStreamAlias("coupon_count")
    private int  couponCount ;

    // 代金券类型  必填[否 ] CASH--充值代金券 NO_CASH---非充值优惠券 开通免充值券功能，并且订单使用了优惠券后有返回（取值：CASH、NO_CASH）。$n为下标,从0开始编号，举例：coupon_type_$0
    @XStreamAlias("coupon_type_$n")
    private String couponType_$n ;

    // 代金券ID  必填[否 ] 代金券ID, $n为下标，从0开始编号
    @XStreamAlias("coupon_id_$n")
    private String couponId_$n ;

    // 单个代金券支付金额  必填[否 ] 单个代金券支付金额, $n为下标，从0开始编号
    @XStreamAlias("coupon_fee_$n")
    private int  couponFee_$n ;

    // 微信支付订单号  必填[是 ] 微信支付订单号
    @XStreamAlias("transaction_id")
    private String  transactionId ;

    // 商户订单号  必填[是 ] 商户系统内部订单号，要求32个字符内，只能是数字、大小写字母_-|*@ ，且在同一个商户号下唯一。
    @XStreamAlias("out_trade_no")
    private String  outTradeNo ;

    // 附加数据  必填[否 ] 附加数据，原样返回
    private String  attach ;

    // 支付完成时间  必填[是 ] 订单支付时间，格式为yyyyMMddHHmmss，如2009年12月25日9点10分10秒表示为20091225091010。其他详见时间规则
    @XStreamAlias("time_end")
    private String  timeEnd ;

    // 交易状态描述  必填[是 ] 对当前查询订单状态的描述和下一步操作的指引
    @XStreamAlias("trade_state_desc")
    private String  tradeStateDesc;

    public String getReturnCode() {
        return returnCode;
    }

    public Optional<String> getReturnMsg() {
        return Optional.ofNullable(returnMsg);
    }

    public String getAppid() {
        return appid;
    }

    public String getMchId() {
        return mchId;
    }

    public String getNonceStr() {
        return nonceStr;
    }

    public String getSign() {
        return sign;
    }

    @Override
    public String getResultCode() {
        return resultCode;
    }

    @Override
    public String getErrCode() {
        return errCode;
    }

    @Override
    public String getErrCodeDes() {
        return errCodeDes;
    }

    public String getDeviceInfo() {
        return deviceInfo;
    }

    public String getOpenid() {
        return openid;
    }

    public String getIsSubscribe() {
        return isSubscribe;
    }

    public String getTradeType() {
        return tradeType;
    }

    public String getTradeState() {
        return tradeState;
    }

    public String getBankType() {
        return bankType;
    }

    public int getTotalFee() {
        return totalFee;
    }

    public int getSettlementTotalFee() {
        return settlementTotalFee;
    }

    public String getFeeType() {
        return feeType;
    }

    public int getCashFee() {
        return cashFee;
    }

    public String getCashFeeType() {
        return cashFeeType;
    }

    public int getCouponFee() {
        return couponFee;
    }

    public int getCouponCount() {
        return couponCount;
    }

    public String getCouponType_$n() {
        return couponType_$n;
    }

    public String getCouponId_$n() {
        return couponId_$n;
    }

    public int getCouponFee_$n() {
        return couponFee_$n;
    }

    public String getTransactionId() {
        return transactionId;
    }

    public String getOutTradeNo() {
        return outTradeNo;
    }

    public String getAttach() {
        return attach;
    }

    public String getTimeEnd() {
        return timeEnd;
    }

    public String getTradeStateDesc() {
        return tradeStateDesc;
    }

    public boolean paidSuccess() {
        return "SUCCESS".equals(this.getTradeState());
    }

    /**
     * 获取Date格式的支付成功时间。
     * 如果获取错误，将返回当前时间
     * @return
     */
    public Date getTimeEndForDate(){
        try {
            return DateUtils.parseDate(getTimeEnd(),"yyyyMMddHHmmss");
        } catch (ParseException e) {
            return new Date();
        }
    }

}
